package com.cloudcc.mobile.weight;


import java.util.Calendar;
import java.util.Date;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ViewFlipper;

import com.cloudcc.mobile.R;


public class SwipeCalendarView extends ViewGroup {
	private ViewFlipper mFlipper;
	private GridView mGridView;
	public BaseAdapter mAdapter;
	private int mColNum = 7;
	private Style mStyle = Style.WEEK; // 样式
	private GestureDetector mGestureDetector = new GestureDetector(new MyGestureListener());
	private Date mSelectDate;//当前选择的日期
	private Date[] dayNumber;
	private Date mCurrentShowDate;
	private int mTouchSlop;
	private OnAdapterChange mOnAdapterChange;
	private OnLocationChangeListener mOnLocationChangeListener;
	private OnCalendarChangeListener mOnGetItemViewListener;
	private OnDayItemSelectListener mOnDayItemSelectListener;
	

	public SwipeCalendarView(Context context) {
		this(context, null);
	}

	public SwipeCalendarView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public SwipeCalendarView(Context context, AttributeSet attrs,
			int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		mCurrentShowDate = new Date();
		mSelectDate = new Date();
		mTouchSlop = ViewConfiguration.get(getContext()).getTouchSlop();
	}
	
	/**设置选中的日期
	 * @param date
	 */
	public void SelectData(Date date){
		mSelectDate =date;
	}
	
	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		initViews();
	}

	public enum Style {
		WEEK, MONTH
	}

	public Date getmSelectDate() {
		return mSelectDate;
	}

	private void initViews() {

		initFlipper();

		//addGridView();

		if (mStyle == Style.WEEK) {
			showWeekUI(mCurrentShowDate);
		} else {
			showMonthUI(mCurrentShowDate);
		}
	}

	/**
	 * 刷新数据日期
	 * 
	 * @param date
	 */
	private void refreshDateArray(Date date) {
		if (mStyle == Style.WEEK) {
			getDaysByWeek(date);
		} else {
			getDaysByMonth(date);
		}
	}

	/** 获得下一个时间节点 的  信息
	 * @param date
	 * @param step
	 */
	private void getNextOrPreDate(Date date, int step) {
		if (mStyle == Style.WEEK) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			calendar.add(Calendar.DATE, 7 * step);
			mCurrentShowDate = calendar.getTime();
		} else {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			calendar.add(Calendar.MONTH, step);
			mCurrentShowDate = calendar.getTime();
		}
	}

	public void showNext() {
		getNextOrPreDate(mCurrentShowDate, 1);
		refreshDateArray(mCurrentShowDate);
		addGridView();
		mAdapter = new CalendarAdapter(getContext());
		mGridView.setAdapter(mAdapter);
		mFlipper.addView(mGridView, 1);
		mFlipper.setInAnimation(AnimationUtils.loadAnimation(getContext(),
				R.anim.push_left_in));
		mFlipper.setOutAnimation(AnimationUtils.loadAnimation(getContext(),
				R.anim.push_left_out));
		mFlipper.showNext();
		mFlipper.removeViewAt(0);
		if (mOnLocationChangeListener != null) {
			mOnLocationChangeListener.onNext(mCurrentShowDate);
		}
	}

	public void showPrevious() {
		getNextOrPreDate(mCurrentShowDate, -1);
		refreshDateArray(mCurrentShowDate);
		mAdapter = new CalendarAdapter(getContext());
		addGridView();
		mGridView.setAdapter(mAdapter);
		mFlipper.addView(mGridView, 1);
		mFlipper.setInAnimation(AnimationUtils.loadAnimation(getContext(),
				R.anim.push_right_in));
		mFlipper.setOutAnimation(AnimationUtils.loadAnimation(getContext(),
				R.anim.push_right_out));
		mFlipper.showPrevious();
		mFlipper.removeViewAt(0);
		if (mOnLocationChangeListener != null) {
			mOnLocationChangeListener.onPrevious(mCurrentShowDate);
		}
	}

	/**
	 * @Description: 适配器变化的时候
	 * @author wangzhiqiang
	 * @date 2015-11-23 下午10:29:03
	 * 
	 */
	public interface OnAdapterChange {
		CalendarAdapter onCreateAdapter();
	}

	public interface onUIChange {

	}

	public interface OnLocationChangeListener {

		void onNext(Date date);

		void onPrevious(Date date);
		
		void onStyleChange(Style style);
	}

	public OnLocationChangeListener getOnLocationChangeListener() {
		return mOnLocationChangeListener;
	}

	public void setOnLocationChangeListener(
			OnLocationChangeListener mOnLocationChangeListener) {
		this.mOnLocationChangeListener = mOnLocationChangeListener;
	}

	public Date getmCurrentUIDate() {
		return mCurrentShowDate;
	}

	public void showWeekUI(Date date) {
		mStyle = Style.WEEK;
		getDaysByWeek(date);
		addGridView();
		mAdapter = new CalendarAdapter(getContext());
		mGridView.setAdapter(mAdapter);
		if (mFlipper.getChildCount() ==0) {
			mFlipper.addView(mGridView, 0);
			addView(mFlipper);
		}else{
			mFlipper.addView(mGridView, 1);
			mFlipper.setInAnimation(AnimationUtils.loadAnimation(getContext(),
					R.anim.push_set_bottom_in));
			mFlipper.setOutAnimation(null);
			mFlipper.showNext();
			mFlipper.removeViewAt(0);
		}
		if (mOnLocationChangeListener!=null) {
			mOnLocationChangeListener.onStyleChange(mStyle);
		}
		
	}

	public void showMonthUI(Date date) {
		mStyle = Style.MONTH;
		getDaysByMonth(date);
		addGridView();
		mAdapter = new CalendarAdapter(getContext());
		mGridView.setAdapter(mAdapter);
		if (mFlipper.getChildCount() ==0) {
			mFlipper.addView(mGridView, 0);
			addView(mFlipper);
		}else{
			mFlipper.addView(mGridView, 1);
			mFlipper.setInAnimation(null);
			mFlipper.setOutAnimation(null);
			mFlipper.showNext();
			mFlipper.removeViewAt(0);
		}
		if (mOnLocationChangeListener!=null) {
			mOnLocationChangeListener.onStyleChange(mStyle);
		}
	}

	/**
	 * 初始化滑动
	 */
	private void initFlipper() {
		mFlipper = new ViewFlipper(getContext());
		LayoutParams layoutParams = new ViewGroup.LayoutParams(
				ViewGroup.LayoutParams.MATCH_PARENT,
				ViewGroup.LayoutParams.WRAP_CONTENT);
		mFlipper.setLayoutParams(layoutParams);
		mFlipper.setPadding(0, 0, 0, 0);
		mFlipper.removeAllViews();
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {

		mFlipper.layout(0, 0, r, mFlipper.getMeasuredHeight());
	}

	private void addGridView() {
		ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		mGridView = new GridView(getContext());
		mGridView.setNumColumns(mColNum);
		mGridView.setGravity(Gravity.CENTER_VERTICAL);
		mGridView.setSelector(new ColorDrawable(Color.TRANSPARENT));
		// 去除gridView边框
		mGridView.setVerticalSpacing(1);
		mGridView.setHorizontalSpacing(1);
		mGridView.setLayoutParams(params);
		mGridView.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				return mGestureDetector.onTouchEvent(event);
			}
		});
		mGridView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				//如果不是本月的不能点击
				Date preSelectDate = dayNumber[position];
				boolean sameMonth = com.cloudcc.mobile.util.DateUtils
						.isSameMonth(preSelectDate,mCurrentShowDate);
				if (sameMonth&&mOnDayItemSelectListener!=null) {
					mSelectDate = dayNumber[position];
					mCurrentShowDate =mSelectDate;
					mAdapter.notifyDataSetChanged();
					if (mOnDayItemSelectListener!=null) {
						mOnDayItemSelectListener.OnItemSelected(position, mSelectDate);
					}
				}

			}
		});
	}

	private Date getDate(Date date, int dayInMonth) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DATE, dayInMonth);
		return calendar.getTime();
	}

	private class MyGestureListener extends SimpleOnGestureListener {
		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			float dx = e1.getX() - e2.getX();
			float dy = e1.getY() - e2.getY();
			if (Math.abs(dx) >= Math.abs(dy)) {
				if (dx > mTouchSlop * 3) {
					showNext();
					return true;
				} else if (dx < -mTouchSlop * 3) {
					showPrevious();
					return true;
				}
			} else {
				if (dy > mTouchSlop) {
					showWeekUI(mCurrentShowDate);
					return true;
				} else if (dy < -mTouchSlop) {
					showMonthUI(mCurrentShowDate);
					return true;
				}
			}
			return false;
		}
	}

	/**
	 * 获取 日期数组 周视图
	 * 
	 * @param date
	 */
	private void getDaysByWeek(Date date) {
		// 当前时间
		dayNumber = new Date[7];
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int j = calendar.get(Calendar.DAY_OF_WEEK);
		calendar.add(Calendar.DATE, Calendar.SUNDAY - j);
		Date[] weekDays = new Date[7];
		weekDays[0] = calendar.getTime();
		for (int i = 1; i < weekDays.length; i++) {
			calendar.add(Calendar.DATE, 1);
			weekDays[i] = calendar.getTime();
		}
		for (int i = 0; i < dayNumber.length; i++) {
			dayNumber[i] = weekDays[i];
		}
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		//super.onMeasure(widthMeasureSpec, widthMeasureSpec);
		
		//测量
		int mWidthMode = MeasureSpec.getMode(widthMeasureSpec);
		int mHeightMode = MeasureSpec.getMode(heightMeasureSpec);
		
		int mWidthSize = MeasureSpec.getSize(widthMeasureSpec);
		int mHeightSize = MeasureSpec.getSize(heightMeasureSpec);
		int nowH =0;
		if (mStyle==Style.WEEK) {
			nowH=(mWidthSize / 7);
		}else{
			nowH=(mWidthSize / 7)*6;
		}
		setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(nowH, MeasureSpec.EXACTLY));
		mFlipper.measure(MeasureSpec.makeMeasureSpec(mWidthSize, MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(nowH, MeasureSpec.EXACTLY));
	}

	/**
	 * 月视图
	 * 
	 * @param date
	 */
	private void getDaysByMonth(Date date) {
		dayNumber = new Date[42];
		// # 获取 当前月份的最小值
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);

		int month = calendar.get(Calendar.MONTH);// 获取 当期月份 中的第几天

		int currentMonthDays = getMonthDays(date,0);// 当前
		int lastMonthDays = getMonthDays(date, -1);// 上月
		
		calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置 当前月份的第一天
		int fristDayInMonthOnWeek = calendar.get(Calendar.DAY_OF_WEEK);// 获取第一天是本周的第几天
		// 上月的
		int index = 0;
		calendar.add(Calendar.MONTH, -1);
		for (int i = lastMonthDays - fristDayInMonthOnWeek + 1; i < lastMonthDays; index++) {
			calendar.set(Calendar.DATE, ++i);
			dayNumber[index] = calendar.getTime();
		}
		// 本月的
		calendar.setTime(date);
		for (int i = 1; i <= currentMonthDays; i++, index++) {
			calendar.set(Calendar.DATE, i);
			dayNumber[index] = calendar.getTime();
		}
		// 下月
		calendar.add(Calendar.MONTH, 1);
		for (int i = 1; index < dayNumber.length; index++, i++) {
			calendar.set(Calendar.DATE, i);
			dayNumber[index] = calendar.getTime();
		}
	}

	/**
	 * 某年某月中的日子
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public int getMonthDays(Date date, int addMoth) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, addMoth);
		int MaxDay = cal.getActualMaximum(Calendar.DATE);
		return MaxDay;
	}

	/** 
	* @Description: 日历的item
	* @author wangzhiqiang
	* @date 2015-12-7 下午4:55:08 
	*  
	*/
	public class CalendarAdapter extends BaseAdapter {

		private Context context;

		public CalendarAdapter(Context context) {
			this.context = context;
		}

		@Override
		public int getCount() {
			return dayNumber.length;
		}

		@Override
		public Date getItem(int position) {
			return dayNumber[position];
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			Date date = getItem(position);
			if (mOnGetItemViewListener != null) {
				return mOnGetItemViewListener.getView(position, convertView,
						date);
			}
			return null;
		}
		@Override
		public void notifyDataSetChanged() {
			if (mOnGetItemViewListener != null) {
				mOnGetItemViewListener.onNotifyDataChanged();
			}
			super.notifyDataSetChanged();
		}
	}
	

	public void setOnCalendarChangeListener(OnCalendarChangeListener onGetItemViewListener) {
		this.mOnGetItemViewListener = onGetItemViewListener;
	}
	/** 设置触摸位置改变的监听
	 * @param listener
	 */
	public void setOnDayItemSelectListener(OnDayItemSelectListener listener){
		this.mOnDayItemSelectListener =listener;
	}

	/** 
	* @Description: 当选中某一天的时候
	* @author wangzhiqiang
	* @date 2015-12-2 下午3:42:56 
	*  
	*/
	public interface OnDayItemSelectListener{
		/**
		 * @param pos 位置
		 * @param date 选中的时间
		 */
		void OnItemSelected(int pos,Date date);
	}
	
	public interface OnCalendarChangeListener {
		/** 获得 item 的view  参考 baseadapter
		 * @param position
		 * @param convertView
		 * @param date
		 * @return
		 */
		View getView(int position, View convertView, Date date);
		
		
		/**
		 * apater 设置 notif 的时候
		 */
		void onNotifyDataChanged();
	}
	
	public Date[] getCurrentDayNum(){
		return dayNumber;
	}
	
}
